package com.sunnay.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sunnay.entity.*;
import com.sunnay.enums.DepositEnum;
import com.sunnay.enums.GbCodeEnum;
import com.sunnay.exception.DataException;
import com.sunnay.mapper.DepositInfoMapper;
import com.sunnay.service.*;
import com.sunnay.util.CommUtils;
import com.sunnay.util.WptUtils;
import com.sunnay.vo.auth.SystemUser;
import com.sunnay.vo.product.BidRequestVo;
import com.sunnay.vo.product.CancelDepositVo;
import com.sunnay.vo.product.DepositVo;
import com.sunnay.vo.product.ProductDetailVo;
import com.sunnay.vo.user.UserInfoVo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Optional;

@Service
@Slf4j
public class DepositInfoServiceImpl extends ServiceImpl<DepositInfoMapper, DepositInfoEntity> implements DepositInfoService {

    @Resource
    private AppUserInfoService userInfoService;

    @Resource
    private AppUserOrderExpireService userOrderExpireService;

    @Resource
    private ShopInfoService shopInfoService;

    @Resource
    private CreateProcessService createProcessService;

    @Resource
    private BidListService bidListService;

    @Value("${sunay.process}")
    private String process;

    @Value("${sunay.server-wechat-deposit}")
    private String serverWechatDeposit;

    @Value("${sunay.server-wechat-member}")
    private String serverWechatMember;

    @Resource
    private UserService userService;

    @Override
    public DepositInfoEntity getDepositInfo(String uri) {
        return this.baseMapper.getDepositInfo(uri);
    }

    @Override
    @Transactional
    public void publishDeposit(DepositVo depositVo, SystemUser systemUser) {
        UserEntity userQueryInfo = userService.getOne(Wrappers.<UserEntity>lambdaQuery().eq(UserEntity::getWxId, systemUser.getWxId()));
        Optional.ofNullable(userQueryInfo).orElseThrow(()->new DataException(GbCodeEnum.USER_NOT_FOUND));

        if(userQueryInfo.getMoney() < 0)
            throw new DataException(GbCodeEnum.USER_MONEY_NOT_LACK);

        DepositInfoEntity depositInfoEntity = this.getOne(Wrappers.<DepositInfoEntity>lambdaQuery().eq(DepositInfoEntity::getSaleUri,depositVo.getSaleUri()).eq(DepositInfoEntity::getStatus,DepositEnum.DEPOSIT_STATUS_1.getKey()));
        if(ObjectUtil.isNotEmpty(depositInfoEntity) && StringUtils.equals(depositInfoEntity.getStatus(),DepositEnum.DEPOSIT_STATUS_1.getKey())){
            depositInfoEntity.setStatus(DepositEnum.DEPOSIT_STATUS_4.getKey());
            depositInfoEntity.setResult(DepositEnum.DEPOSIT_STATUS_4.getValue());
            this.updateById(depositInfoEntity);
            return;
        }
        ProductDetailVo detailVo = getUserInfoVo(systemUser, depositVo.getSaleUri());
        //托管拍品截拍时间不低于2小时
        if((detailVo.getEndTime() - detailVo.getNowTime()) < CommUtils.MAX_END_TIME)
            throw new DataException(GbCodeEnum.USER_DEPOSIT_LOW_TIME.getKey(),GbCodeEnum.USER_DEPOSIT_LOW_TIME.getValue());
        if(depositVo.getAiniMoney() < detailVo.getNowPrice())
            throw new DataException(GbCodeEnum.USER_DEPOSIT_MAX_MONEY.getKey(),GbCodeEnum.USER_DEPOSIT_MAX_MONEY.getValue());
        DepositInfoEntity insert = getDepositInfoEntity(depositVo, systemUser, detailVo);
        this.save(insert);
    }

    @Override
    public void cancelDeposit(CancelDepositVo depositVo) {
        DepositInfoEntity depositInfoEntity = this.getOne(Wrappers.<DepositInfoEntity>lambdaQuery().eq(DepositInfoEntity::getSaleUri,depositVo.getSaleUri()).eq(DepositInfoEntity::getStatus,DepositEnum.DEPOSIT_STATUS_1.getKey()));
        if(StringUtils.equals(depositInfoEntity.getStatus(),DepositEnum.DEPOSIT_STATUS_1.getKey())){
            depositInfoEntity.setStatus(DepositEnum.DEPOSIT_STATUS_4.getKey());
            depositInfoEntity.setResult(DepositEnum.DEPOSIT_STATUS_4.getValue());
            this.updateById(depositInfoEntity);
        }
    }

    @Override
    public void publishBid(BidRequestVo requestVo, SystemUser systemUser) {
        UserEntity userQueryInfo = userService.getOne(Wrappers.<UserEntity>lambdaQuery().eq(UserEntity::getWxId, systemUser.getWxId()));
        Optional.ofNullable(userQueryInfo).orElseThrow(()->new DataException(GbCodeEnum.USER_NOT_FOUND));

        if(userQueryInfo.getMoney() < 0)
            throw new DataException(GbCodeEnum.USER_MONEY_NOT_LACK);


        ProductDetailVo detailVo = getUserInfoVo(systemUser, requestVo.getSaleUri());
        //查看出价进程
        int bidMoney = detailVo.getNowPrice() + detailVo.getIncrease();
        String processId = createProcessService.getProcessId(process);
        BidListEntity bidListEntity = new BidListEntity();
        bidListEntity.setAddMoney(detailVo.getIncrease());
        bidListEntity.setNickName(detailVo.getShopName());
        bidListEntity.setProcess(process);
        bidListEntity.setProcessId(processId);
        bidListEntity.setStartMoney(bidMoney);
        bidListEntity.setSaleUri(requestVo.getSaleUri());
        bidListEntity.setAdminId(61);
        bidListEntity.setEndTime(new Timestamp(detailVo.getEndTime() * 1000));
        bidListEntity.setWxId(systemUser.getWxId());
        bidListEntity.setServerWxId(serverWechatMember);
        this.bidListService.save(bidListEntity);
    }

    private ProductDetailVo getUserInfoVo(SystemUser systemUser,String saleUri) {
        UserInfoVo userInfoVo = userInfoService.userInfo(systemUser);
        if(userInfoVo.getMoney() < 0)
            throw new DataException(GbCodeEnum.APP_USER_NOT_MONEY.getKey(),GbCodeEnum.APP_USER_NOT_MONEY.getValue());
        ProductDetailVo detailVo = WptUtils.productDetailInfo(saleUri);
        Optional.ofNullable(detailVo).orElseThrow(()-> new DataException(GbCodeEnum.USER_DEPOSIT_NOT_MESSAGE.getKey(),GbCodeEnum.USER_DEPOSIT_NOT_MESSAGE.getValue()));
        //拍品已截拍
        if((detailVo.getEndTime() - detailVo.getNowTime()) <= 0)
            throw new DataException(GbCodeEnum.USER_DEPOSIT_END_TIME.getKey(),GbCodeEnum.USER_DEPOSIT_END_TIME.getValue());
        //看是否绑定过微信
        ShopInfoEntity  shopInfoEntity = shopInfoService.getOne(Wrappers.<ShopInfoEntity>lambdaQuery().eq(ShopInfoEntity::getWxId, systemUser.getWxId()).eq(ShopInfoEntity::getShopName,detailVo.getShopName()));
        Optional.ofNullable(shopInfoEntity).orElseThrow(()->new DataException(GbCodeEnum.USER_DEPOSIT_BIND_SHOP.getKey(),GbCodeEnum.USER_DEPOSIT_BIND_SHOP.getValue()));
        //看是否有订单
        int orderNum = userOrderExpireService.count(Wrappers.<AppUserOrderExpireEntity>query().lambda().eq(AppUserOrderExpireEntity::getWxId, systemUser.getId()));
        if(orderNum > 0)
            throw new DataException(GbCodeEnum.USER_DEPOSIT_ORDER_PAY.getKey(),GbCodeEnum.USER_DEPOSIT_ORDER_PAY.getValue());
        return detailVo;
    }

    private DepositInfoEntity getDepositInfoEntity(DepositVo depositVo, SystemUser systemUser, ProductDetailVo detailVo) {
        DepositInfoEntity insert = new DepositInfoEntity();
        insert.setNickName(detailVo.getShopName());
        insert.setStatus(DepositEnum.DEPOSIT_STATUS_1.getKey());
        insert.setBeforeMin(depositVo.getBeforeHour() * 60 * 60);
        insert.setAiniMoney(depositVo.getAiniMoney());
        insert.setClientWxId(serverWechatDeposit);
        insert.setSaleUri(depositVo.getSaleUri());
        insert.setRecWxId(systemUser.getWxId());
        insert.setEndTime(new Timestamp(detailVo.getEndTime()*1000));
        insert.setCurrentMoney(detailVo.getNowPrice());
        insert.setMarkUpRange(detailVo.getIncrease());
        return insert;
    }
}
